/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package bzk3.geometry;

import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Random;

import br.odb.liboldfart.wavefront_obj.WavefrontOBJLoader;
import br.odb.libscene.Material;
import br.odb.libscene.Mesh;
import br.odb.libscene.SceneObject;
import br.odb.utils.math.Vec3;

/**
 * 
 * @author daniel
 */
public class ObjMesh extends SceneObject {
	/*
	public static ObjMesh makeCubeObjMesh() {
		ObjMesh cube = new ObjMesh();
		cube.internalize(
				EngineActivity.getInstanceResources().openRawResource(
						R.raw.cube), null);

		return cube;
	}
	*/
	private Material currentMaterial;
	private InputStream materialData;
	private HashMap<String, Material> materialList;
	Mesh mesh;
	public ArrayList<Vec3> verteces;

	public ObjMesh() {
		super();
		materialList = new HashMap<String, Material>();
		verteces = new ArrayList<Vec3>();
		currentMaterial = null;
		new Random();
	}

	public ObjMesh(ObjMesh other) {
		this(other.getMeshes());
	}

	public ObjMesh(ArrayList<Mesh> meshes) {
		this();

		for (int c = 0; c < meshes.size(); ++c)
			addMesh(new Mesh(meshes.get(c)));
	}

	private Material getMaterialByName(String name) {
		return (Material) materialList.get(name);
	}

	String getSubToken(String main, int token) {
		String work = main;
		String toreturn = null;
		while (token > -1) {
			if (token == 0) {
				if (work.indexOf(' ') != -1) {
					toreturn = work.substring(0, work.indexOf(' '));
				} else {
					toreturn = work;
				}
			}

			if (work.indexOf(' ') != -1) {
				work = work.substring(work.indexOf(' ') + 1);
			}

			token--;
		}

		return toreturn;
	}

	public void internalize(InputStream filecontent, InputStream materialData) {
		/*
		 * PARA FAZER FUNCIONAR, TEM QUE IMPLEMENTAR GENERALPOLYGON E FAZER A
		 * PONTE ENTRE ELE E TRIANGLE E SQUARE
		 * 
		 * AINDA PRECISA?!
		 */
		// WavefrontOBJLoader loader = new WavefrontOBJLoader();
		// loader.preBuffer( filecontent, materialData );
		// loader.parseDocument();
		// ArrayList<Mesh> meshes = loader.getGeometry();
		//
		// for ( int c = 0; c < meshes.size(); ++c ) {
		// addMesh( new GLESMesh( meshes.get( c ) ) );
		// }

		this.materialData = materialData;

		String Sub = null;
		int pos = 0;
		char head;

		try {
			while (filecontent.available() != 0) {
				head = (char) filecontent.read();
				if (pos == 0 || head == '\n') {
					if (Sub != null && Sub.length() > 0) {
						Parse(Sub);
					}
					Sub = new String();
				}
				if (head != '\n') {
					Sub += head;
				}
				pos++;
			}
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

	}

	private void Parse(String Sub) {
		Vec3 origin = getPosition();
		switch (Sub.charAt(0)) {
		case 'v':
			verteces.add(new Vec3(origin.getX()
					+ Float.parseFloat(getSubToken(Sub, 1)), origin.getY()
					+ Float.parseFloat(getSubToken(Sub, 2)), origin.getZ()
					+ Float.parseFloat(getSubToken(Sub, 3))));
			break;
		case 'm': {
			if (materialData != null) {

				Material[] mats = WavefrontOBJLoader
						.parseMaterials(materialData);
				if (mats != null)
					for (int c = 0; c < mats.length; ++c)
						materialList.put(mats[c].getName(), mats[c]);

			}
		}
			break;
		case 'u':
			currentMaterial = getMaterialByName(getSubToken(Sub, 1));

			break;
		case 'o':
			mesh = new Mesh( getSubToken(Sub, 1) );
			addMesh(mesh);
			break;

		case 'f':
			Vec3 v1 = (Vec3) verteces.get(Integer.parseInt(getSubToken(
					Sub, 1)) - 1);
			Vec3 v2 = (Vec3) verteces.get(Integer.parseInt(getSubToken(
					Sub, 2)) - 1);
			Vec3 v3 = (Vec3) verteces.get(Integer.parseInt(getSubToken(
					Sub, 3)) - 1);
			{
				int color = 0;

				if (currentMaterial != null)
					color = (int) currentMaterial.getMainColor().getARGBColor();

				mesh.addFace(GLES1TriangleFactory.getInstance().makeTrig(v1.getX(),
						v1.getY(), v1.getZ(), v2.getX(), v2.getY(), v2.getZ(),
						v3.getX(), v3.getY(), v3.getZ(), color));
			}
			break;
		}
	}
}
